具体代码如下:

/***********************semaphore.h*****************************
Semaphore类用于模拟信号量
用法如:Semaphore sem(1);
(1)要求初始信号量值非负
(2)信号量P操作:  sem.P();
(3)信号量V操作:  sem.V();
 
 
****************************************************/
 
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include <windows.h>
class Semaphore{
protected:
HANDLE sem;
public:
//Semaphore();
//void SetValve(int SemValue);
Semaphore(unsigned int SemValue);
virtual ~Semaphore();
void P();
void V();
};
 
#endif
 
 

申明过后是定义文件:


/*****************************semaphore.cpp************************************/
#include <windows.h>
#include <LIMITS.H>
#include <assert.h>
#include "semaphore.h"
 
 
Semaphore::Semaphore(unsigned int semValue){
if(semValue > LONG_MAX)
semValue = LONG_MAX;
sem = CreateSemaphore(NULL,semValue,LONG_MAX,NULL);
}
 
Semaphore::~Semaphore(){
CloseHandle(sem);
}
 
void Semaphore::P(){
DWORD dw = WaitForSingleObject(sem, INFINITE);
 
assert(dw == WAIT_OBJECT_0);
}
 
void Semaphore::V(){
ReleaseSemaphore(sem,1,NULL);
}
 
 

然后是线程头文件

/*****************************thread.h*************************************
 
通过startThread开启线程
startThread(PTHREAD_START func,void * param);
用法:
//定义一个PTHREAD_START类型的函数func
unsigned int WINAPI func (void * param){
//...
return 0;
}
//启动一个线程使其执行func函数
startThread(func,NULL);
 
 
 
********************************************************************/
 
#ifndef THREAD_H
#define THREAD_H
#include <windows.h>
#include <process.h>
/*
from MSDN :
Start address of a routine that begins execution of a new thread.
For _beginthread, the calling convention is either __cdecl or __clrcall;
for _beginthreadex, it is either __stdcall or __clrcall.
WINAPI即为__stdcall
*/
typedef unsigned int (WINAPI *PTHREAD_START) (void *);
 
/*
chBEGINTHREADEX  is From <Windows Via C & C++>
 
*/
#define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \
pvParam, dwCreateFlags, pdwThreadId)                 \
((HANDLE)_beginthreadex(                          \
(void *)        (psa),                         \
(unsigned)      (cbStackSize),                 \
(PTHREAD_START) (pfnStartAddr),                \
(void *)        (pvParam),                     \
(unsigned)      (dwCreateFlags),               \
(unsigned *)    (pdwThreadId)))
// rename chBEGINTHREADEX to startThread for simplicity
#define startThread(pfnStartAddr,pvParam)\
chBEGINTHREADEX(NULL, 0, (pfnStartAddr),(pvParam), 0, NULL)
 
 
#endif
 
 

最后是驱动程序

/*****************************main函数(主函数)************************************/
假设偶数号哲学家先拿左边的筷子,右边的哲学家先拿起右边的筷子。
#include <windows.h>
#include "semaphore.h"
#include "thread.h"
#include <iostream.h>
#include <stdio.h>
#define  N  6                                            //哲学家的个数
#define  LEFT(i)    (i+N-1)%N                            //左边的筷子
#define  RIGHT(i)   (i==N-1)?0:(i+N)%N                   //右边的筷子 编号为N的哲学家的右边的筷子编号为0
 
/*******************************初始化信号量**************************************/
Semaphore ChopStick[N]={Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1)} ;
 
 
 
/*******************************哲学家状态*******************************************/
void Eating(int Ph_Id)
{
printf("Philosopher%d: \tI'm eating......\t",(int)Ph_Id);
}
 
void Sleeping(int Ph_Id)
{
printf("Philosopher%d:\tI'm sleeping......\t",(int)Ph_Id);
Sleep(rand()%10000);
}
void Thinking(int Ph_Id)
{
printf("Philosopher%d: \tI'm thinking......\t",(int)Ph_Id);
}
 
 
 
/********************************************************************/
void Philosopher(int pid){
while (true)
{
if (pid%2 == 0)                 //偶数号哲学家
{
Thinking(pid);              //等待中
ChopStick[LEFT(pid)].P();   //先拿起左边的筷子,再拿起右边的筷子
ChopStick[RIGHT(pid)].P();
Eating(pid);                //获得的两个信号量则eating
ChopStick[LEFT(pid)].V();   //先后释放左右信号量
ChopStick[RIGHT(pid)].V();
printf("\n");
}
else if(pid%2==1 )             //奇数号哲学家
{
Thinking(pid);
ChopStick[RIGHT(pid)].P();  //先拿起右边的筷子,再拿起左边的筷子
ChopStick[LEFT(pid)].P();
Eating(pid);                //左右都得到筷子后则eating
ChopStick[RIGHT(pid)].V();  //先后释放右左信号量
ChopStick[LEFT(pid)].V();
printf("\n");
}
Sleeping(pid);                   //吃完睡上一会儿
}
}
 
 
 
int main(){
HANDLE hPhilosopher[N];    //为每个哲学家分配一个线程
int count =0 ;
for (int Philosopher_id =0 ;Philosopher_id<N;Philosopher_id++)       //开启线程
{
hPhilosopher[Philosopher_id] = startThread(Philosopher,Philosopher_id);
if(count>5)
break;
}
::WaitForMultipleObjects(N,hPhilosopher,TRUE,INFINITE);
for (Philosopher_id = 0 ; Philosopher_id<N;Philosopher_id++)
{
CloseHandle(hPhilosopher[Philosopher_id]);
}
 
return 0;
}